package com.miku.project.controller;

import cn.hutool.core.io.FileUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.miku.mikuapicommon.model.entity.InterfaceInfo;
import com.miku.mikuapicommon.model.entity.User;
import com.miku.project.common.BaseResponse;
import com.miku.project.common.ErrorCode;
import com.miku.project.common.ResultUtils;
import com.miku.project.exception.BusinessException;
import com.miku.project.model.enums.FileUploadBizEnum;
import com.miku.project.model.enums.ImageStatusEnum;
import com.miku.project.model.file.UploadFileRequest;
import com.miku.project.model.vo.ImageVo;
import com.miku.project.model.vo.UserVO;
import com.miku.project.service.InterfaceInfoService;
import com.miku.project.service.UserService;
import com.miku.project.utils.AliOssUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.Arrays;

/**
 * 文件接口
 */
@RestController
@RequestMapping("/file")
@Slf4j
@Api(tags = "文件接口")
public class FileController {
    //上传图片的最大大小不能超过2M
    private static final long MAX_SIZE = 2 * 1024 * 1024;
    @Resource
    private UserService userService;

    @Autowired
    private AliOssUtil aliOssUtil;
    @Resource
    private InterfaceInfoService interfaceInfoService;



    /**
     * 上传文件接口
     * @param file
     * @param uploadFileRequest
     * @param request
     * @return
     */
    @PostMapping("/upload")
    @ApiOperation("上传文件")
    @Transactional(rollbackFor = Exception.class)
    public BaseResponse<ImageVo> uploadFile(@RequestPart("file") MultipartFile file, UploadFileRequest uploadFileRequest, HttpServletRequest request) {

        String biz = uploadFileRequest.getBiz();
        FileUploadBizEnum uploadBizEnum = FileUploadBizEnum.getEnumByValue(biz);
        ImageVo imageVo = new ImageVo();

        if (uploadBizEnum == null){
            return uploadError(imageVo,file,"业务类型为空");
        }

        UserVO loginUser = userService.getLoginUser(request);
        //校验参数
        String result = validFile(file, uploadBizEnum);
        if (!"success".equals(result)){
            return uploadError(imageVo,file,result);
        }
        //文件目录:根据业务,用户来划分
        String fileName=loginUser.getId()+"_"+file.getOriginalFilename();
        //文件路径:业务类型+用户id+文件名
        String filsPath=String.format("%s/%s/%s",uploadBizEnum.getValue(),loginUser.getId(),fileName);
        //上传文件
        try {
            byte[] bytes = file.getBytes();
            String upload = aliOssUtil.upload(bytes, filsPath);
            //如果是头像,更新用户数据库
            if (FileUploadBizEnum.USER_AVATAR.equals(uploadBizEnum)){
                boolean update = userService.update(Wrappers.<User>lambdaUpdate().eq(User::getId, loginUser.getId()).set(StringUtils.isNotEmpty(upload), User::getUserAvatar, upload)
                        .set(User::getUpdateTime, LocalDateTime.now()));
                if (!update){
                    return uploadError(imageVo,file,"上传到用户失败");
                }
            }else {
                if (uploadFileRequest.getInterfaceId()==null){
                    throw new BusinessException(ErrorCode.PARAMS_ERROR,"接口id不能为空");
                }
                //如果是接口头像,更新接口数据库
                boolean update = interfaceInfoService.update(Wrappers.<InterfaceInfo>lambdaUpdate().eq(InterfaceInfo::getId, uploadFileRequest.getInterfaceId())
                        .set(StringUtils.isNotEmpty(upload), InterfaceInfo::getUrl, upload)
                        .set(InterfaceInfo::getUpdateTime, LocalDateTime.now()));
                if (!update){
                    return uploadError(imageVo,file,"上传到接口失败");
                }
            }
            imageVo.setUrl(upload);
            imageVo.setStatus(ImageStatusEnum.SUCCESS.getValue());
            imageVo.setName(file.getOriginalFilename());
            return ResultUtils.success(imageVo);
        } catch (Exception e) {
            return uploadError(imageVo,file,"上传文件失败");
        }
    }

    /**
     * 有效文件校验
     * @param file-文件
     * @param uploadBizEnum-业务类型
     */
    private String validFile(MultipartFile file, FileUploadBizEnum uploadBizEnum) {
        //文件大小
        long size = file.getSize();
        //文件后缀
        String fileSuffix = FileUtil.getSuffix(file.getOriginalFilename());
        if (FileUploadBizEnum.USER_AVATAR.equals(uploadBizEnum)){
            if (size>MAX_SIZE){
                return "文件大小不能超过2M";
            }
            if (!Arrays.asList("jpeg", "jpg", "svg", "png", "webp", "jfif").contains(fileSuffix)){
                return "文件格式不匹配";
            }
        }
        return "success";
    }

    /**
     * 文件上传失败
     * @param imageVo
     * @param file
     * @param message
     * @return
     */
    private BaseResponse<ImageVo> uploadError(ImageVo imageVo, MultipartFile file, String message) {
        imageVo.setName(file.getOriginalFilename());
        imageVo.setUid(RandomStringUtils.random(8));
        imageVo.setStatus(ImageStatusEnum.ERROR.getValue());
        return  ResultUtils.error(imageVo, ErrorCode.OPERATION_ERROR, message);
    }
}
